#ifndef __I2C_SOFT_DRV_H__
#define __I2C_SOFT_DRV_H__
#include <stdio.h>
#include "delay.h"
#include <stdint.h>
#include "gd32f30x.h"

typedef enum {
    I2C_RESULT_OK = 11,      // 成功
    I2C_ERR_DEVICE_ADDR,    // 发送设备地址错误
    I2C_ERR_REGISTER_ADDR,  // 发送寄存器地址错误
    I2C_ERR_WRITE,          // 写数据时出现错误
    I2C_ERR_READ,           // 读数据时出现错误
    I2C_ERR_SLAVE_NO_ACK,   // 从机没有响应
    OTHER_ERR,              // 其他错误
} I2cStatusCode_e;


//SCL引脚配置
#define I2C_SCL_PORT   GPIOB
#define I2C_SCL_PIN    GPIO_PIN_6
#define I2C_SCL_RCU    RCU_GPIOB
#define SCL(bit) 	            gpio_bit_write(I2C_SCL_PORT, I2C_SCL_PIN, bit == 1? SET : RESET)
#define GET_SCL_PIN_STATE()    gpio_input_bit_get(I2C_SCL_PORT, I2C_SCL_PIN)

//SDA引脚配置
#define I2C_SDA_PORT   GPIOB
#define I2C_SDA_PIN    GPIO_PIN_7
#define I2C_SDA_RCU    RCU_GPIOB
#define SDA(bit) 	            gpio_bit_write(I2C_SDA_PORT, I2C_SDA_PIN, bit == 1? SET : RESET)
#define GET_SDA_PIN_STATE()    gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN)

// 修改SDA输入输出模式 --默认是输出 SDA在不通场景下 由不同设备控制
#define  SET_SDA_MODE_OUT()       gpio_init(I2C_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, I2C_SDA_PIN)
#define  SET_SDA_MODE_IN()        gpio_init(I2C_SDA_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, I2C_SDA_PIN)

// 延时的时间直接影响 I2C的发送频率: SCL高  I2C_DELAY() SCL低  T=2*5us =10us   1/10=100kHZ
#define I2C_DELAY()  DelayNus(5)

// 重试次数  等待从机响应 每 I2C_DELAY()--5us 时间读取一次 等待时长 = RETRY_TIMES * I2C_DELAY() =10*5=50us
#define RETRY_TIMES 10



/**
 * @desc  : I2C软实现初始化
 * @date  : 2024-11-21
 * @author: AnRui
 */
void I2cSoftDrvInit(void);

/**
 * @desc  : I2C 写数据
 * @date  : 2024-11-20
 * @author: AnRui
 * @param :  addr -{设备地址 7位}: 不是写地址或读地址
 * @param :  reg  -{寄存器地址}:
 * @param :  data -{保存数据的数组的指针}:
 * @param :  len  -{数组长度}:
 * @return:
 */
I2cStatusCode_e I2cSoftWrite(uint8_t addr, uint8_t reg, uint8_t* data, uint32_t len);

/**
 * @desc  : 读数据
 * @date  : 2024-11-19
 * @author: AnRui
 * @param :  addr -{设备地址 7位}:
 * @param :  reg  -{寄存器地址}:
 * @param :  data -{保存数据的数组的指针}:
 * @param :  len  -{数组长度}:
 * @return:
 */
I2cStatusCode_e I2cSoftRead(uint8_t addr, uint8_t reg, uint8_t* data, uint32_t len);



/**
 * @desc  : 等待从机准备完毕
 * @date  : 2025-04-25
 * @author: AnRui
 * @param : addr - {参数说明}: 从机地址 注意不是写地址或读地址 是地址
 * @param : delayTimes - {参数说明}: 等待次数
 * @return: I2cStatusCode_e
 * @note  : 等待从机准备完毕 例如Eeprom 每写一页数据 都需要等待一段时间 最大5ms
 *          在内部准备的时间内 从机是不响应的
 *          等待次数*60us=最长等待时间 ->例如 delayTimes=100 100*60us=6ms
 */
I2cStatusCode_e WaitDeviceIsReady(uint8_t addr, uint32_t delayTimes);

#endif // __I2C_SOFT_DRV_H__
